package com.example.hystrixDemo.controller;

import com.alibaba.fastjson.JSONObject;
import com.example.hystrixDemo.service.collaspers.HystrixCommandSingle;
import com.example.hystrixDemo.service.collaspers.QueryService;
import com.example.hystrixDemo.service.impl.LoanServiceImpl;
import com.example.hystrixDemo.service.impl.OrderHystrixCommand;
import com.example.hystrixDemo.service.observable.imp.UserInfoServiceCommand;
import com.example.hystrixDemo.service.observable.imp.UserInfoServiceInfoCommand1;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import rx.Observable;

import java.util.Iterator;

@RestController
@RequestMapping(value = "/hystrix")
public class HystrixDemoController {
    private final Logger logger = LoggerFactory.getLogger(HystrixDemoController.class);
    @Autowired
    Environment environment;
    @Autowired
    private OrderHystrixCommand orderHystrixCommand;
    @Autowired
    private LoanServiceImpl loanService;
    @Autowired
    private QueryService queryService;
//    @Autowired
//    private UserInfoServiceCommand userInfoServiceCommand;


    @RequestMapping(value = "/demo1")
    public String demo1(){
        logger.info("=========demo1当前端请求线程:{}=========", Thread.currentThread().getName());
        String execute = orderHystrixCommand.execute();
        return execute;
    }

    @RequestMapping(value = "/demo2")
    public String demo2() throws InterruptedException {
        logger.info("=========demo2当前端请求线程:{}=========", Thread.currentThread().getName());
        String execute = loanService.queryLoanResult();
        return execute;
    }

    @RequestMapping(value = "/demo3")
    public String demo3() throws InterruptedException {
        logger.info("=========demo3当前端请求线程:{}=========", Thread.currentThread().getName());
        //每个Command对象只能调用一次,不可以重复调用,
        //重复调用对应异常信息:This instance can only be executed once. Please instantiate a new instance.  所以用new出来的对象
        UserInfoServiceCommand userInfoServiceCommand = new UserInfoServiceCommand();
        Observable<String> observe = userInfoServiceCommand.observe();
        Iterator<String> iterator = observe.toBlocking().getIterator();
        String result = "";
        while (iterator.hasNext()){
            logger.info("=========oberver结果:{}=========", iterator.next().toString());
            result += "," + iterator.next().toString();
        }

        return result;
    }

    @RequestMapping(value = "/demo4")
    public String demo4() throws InterruptedException {
        logger.info("=========demo4当前端请求线程:{}=========", Thread.currentThread().getName());
        String result = "";
        //每个Command对象只能调用一次,不可以重复调用,
        //重复调用对应异常信息:This instance can only be executed once. Please instantiate a new instance.  所以用new出来的对象
        UserInfoServiceCommand userInfoServiceCommand = new UserInfoServiceCommand();
        Observable<String> observe = userInfoServiceCommand.observe();
//        observe.subscribe(new Observer<String>() {
//            @Override
//            public void onCompleted() {
//
//                logger.info("=========完成了:{}=========");
//
//            }
//
//            @Override
//            public void onError(Throwable e) {
//                logger.info("=========demo4报错了:{}=========", e);
//
//            }
//
//            @Override
//            public void onNext(String s) {
//
//                logger.info("=========oberver结果:{}=========", s);
//
//            }
//        });

        return result;
    }


    @RequestMapping(value = "/demo5")
    public String demo5() throws InterruptedException {
        logger.info("=========demo5当前端请求线程:{}=========", Thread.currentThread().getName());
        String result = "";
        //每个Command对象只能调用一次,不可以重复调用,
        //重复调用对应异常信息:This instance can only be executed once. Please instantiate a new instance.  所以用new出来的对象
        UserInfoServiceInfoCommand1 userInfoServiceInfoCommand1 = new UserInfoServiceInfoCommand1();
        Observable observe = userInfoServiceInfoCommand1.toObservable();
//        observe.subscribe(new Observer<String>() {
//            @Override
//            public void onCompleted() {
//                logger.info("=========demo5完成了:{}=========");
//
//            }
//
//            @Override
//            public void onError(Throwable e) {
//
//                logger.info("=========demo5报错了:{}=========", e);
//
//            }
//
//            @Override
//            public void onNext(String string) {
//                logger.info("=========demo5结果:{}=========", string);
//
//
//            }
//        });

        return result;
    }
    @RequestMapping(value = "/demo6")
    public String demo6() throws InterruptedException {
        logger.info("=========demo6当前端请求线程:{}=========", Thread.currentThread().getName());
        Iterator<String> iterator = loanService.queryLoanResult1().toBlocking().getIterator();
        String result  = "";
//        while (iterator.hasNext()) {
//            result += "," + result;
//        }

        return result;

    }


    /**
     * 使用信号量隔离
     * @return
     * @throws InterruptedException
     */
    @RequestMapping(value = "/demo7")
    public String demo7() throws Exception {
        logger.info("=========demo7当前端请求线程:{}=========", Thread.currentThread().getName());
        String result2 = loanService.queryLoanResult2();
        return result2;

    }

    /**
     * 请求合并
     * @return
     * @throws InterruptedException
     */
    @RequestMapping(value = "/demo8")
    public String demo8(@RequestBody String param) throws Exception {
        logger.info("=========demo8当前端请求线程:{}=========", Thread.currentThread().getName());
        JSONObject jsonObject = JSONObject.parseObject(param, JSONObject.class);
        String id = jsonObject.getString("id");
        HystrixCommandSingle hystrixCommandSingle = new HystrixCommandSingle(queryService, id);
        String run = hystrixCommandSingle.run();
        return run;

    }


    private String getPort(){
        return environment.getProperty("local.server.port");
    }
}
